为了加快页面渲染,我们常使用先缓存后网络(
StaleWhileRevalidate)策略将本地缓存作为响应快速返回给用户,同时从网络中获取最新资源并更新缓存,最后通知页面进行更新。由于 Service Worker 与页面运行在不同的线程环境中,故需要一种机制来保证缓存更新后页面能够及时得到通知。在 Workbox 中,我们可以使用workbox-broadcast-cache-update模块来实现这一需求,接下来就让我们一起来探究该模块的使用
# 基本使用
workbox.routing.registerRoute(
'/articles',
new workbox.strategies.StaleWhileRevalidate({
plugins: [
new workbox.broadcastUpdate.Plugin({
channelName: 'workbox',
deferNoticationTimeout: 1000,
headersToCheck: ['Content-Length', 'ETag', 'Last-Modified']
})
]
})
);
@前端进阶之旅: 代码已经复制到剪贴板
上例中,当请求
/articles的缓存更新后,只要新响应头信息中Content-Length、ETag或Last-Modified的值有任何一个与旧响应头信息中相关属性的值不一致,便会向频道 workbox 广播缓存更新消息。其中workbox.broadcastUpdate.Plugin构造函数的参数为含有以下属性的对象:
channelName:频道名称(默认值为workbox)。headersToCheck:出于效率的考量,Workbox 通过比对前后两个响应的头信息来判断响应是否更新,我们可通过该属性来设置需比对的头信息(默认值为content-length、etag和last-modified)。deferNoticationTimeout:当请求为导航请求,且相关缓存有所更新时,Workbox 会延迟广播直到页面准备妥当(页面可通过调用navigator.serviceWorker.controller.postMessage发送{type: 'WINDOW_READY', meta: 'workbox-window'}消息来告知Workbox),同时也为了避免无限制地等待,我们可通过该属性以要求 Workbox 在等待指定时间后,无论是否收到页面通知,都将立即广播更新消息(默认值为1000,单位为毫秒)
由于
workbox.broadcastUpdate.Plugin内部使用了workbox.broadcastUpdate.BroadcastCacheUpdate来处理缓存更新广播,因此在自定义的请求策略中,可直接使用它来处理缓存更新广播,比如:
const broadcastUpdate = new workbox.broadcastUpdate.BroadcastCacheUpdate({
channelName: 'workbox',
deferNoticationTimeout: 1000,
headersToCheck: ['Content-Length', 'ETag', 'Last-Modified']
});
const cacheName = 'cacheName';
const url = 'http:/127.0.0.1:8080/articles';
const cache = await caches.open(cacheName);
const oldResponse = await cache.match(url);
const newResponse = await fetch(url);
broadcastUpdate.notifyIfUpdated({
oldResponse,
newResponse,
url,
cacheName
});
